#include "xsvf_micro.h"
#include "xsvf_ports.h"
#include "define.h"
#include "stdio.h"

extern t_lua_callback_param g_xsvf_callback_param;

/*
typedef struct lua_callback_param
{
    lua_State *_L;

    int callback_ref_setPort;
    int callback_ref_readTDOBit;
    int callback_ref_readByte;
} t_lua_callback_param;
*/

int l_xsvf_process(lua_State *L)
{
    unsigned char data;

    int ret = NO_ERR;
	int table_top = lua_gettop(L);
    g_xsvf_callback_param._L = NULL;

	if(table_top != 3) {
		lua_pushnumber (L, -ERR_PARAM_NUM);
	} else {
		if (lua_type(L,-1) == LUA_TFUNCTION) {
			g_xsvf_callback_param.callback_ref_setPort = luaL_ref(L, LUA_REGISTRYINDEX);//setPort
		} else {
            lua_pushnumber (L, -ERR_PARAM);
            return 1;
		}
        if (lua_type(L,-1) == LUA_TFUNCTION) {
			g_xsvf_callback_param.callback_ref_readTDOBit = luaL_ref(L, LUA_REGISTRYINDEX);//readTDOBit
		} else {
            luaL_unref(L, LUA_REGISTRYINDEX, g_xsvf_callback_param.callback_ref_setPort);
            lua_pushnumber (L, -ERR_PARAM);
            return 1;
		}
        if (lua_type(L,-1) == LUA_TFUNCTION) {
			g_xsvf_callback_param.callback_ref_readByte = luaL_ref(L, LUA_REGISTRYINDEX);//readByte
		} else {
            luaL_unref(L, LUA_REGISTRYINDEX, g_xsvf_callback_param.callback_ref_setPort);
            luaL_unref(L, LUA_REGISTRYINDEX, g_xsvf_callback_param.callback_ref_readTDOBit);
            lua_pushnumber (L, -ERR_PARAM);
            return 1;
		}
        g_xsvf_callback_param._L = L;

        ret = xsvfExecute();

        g_xsvf_callback_param._L = NULL;
        luaL_unref(L, LUA_REGISTRYINDEX, g_xsvf_callback_param.callback_ref_setPort);
        luaL_unref(L, LUA_REGISTRYINDEX, g_xsvf_callback_param.callback_ref_readTDOBit);
        luaL_unref(L, LUA_REGISTRYINDEX, g_xsvf_callback_param.callback_ref_readByte);
        
        lua_pushnumber (L, ret);
	}
    return 1;
}